package com.jhgsys.internal.hazard.controller;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jhgsys.internal.base.entity.BaseCautionaryLesson;
import com.jhgsys.internal.base.entity.BaseProject;
import com.jhgsys.internal.base.entity.HazardExamineUser;
import com.jhgsys.internal.base.service.IBaseCautionaryLessonService;
import com.jhgsys.internal.base.service.IBaseProjectService;
import com.jhgsys.internal.base.service.IHazardExamineUserService;
import com.jhgsys.internal.common.annotation.Log;
import com.jhgsys.internal.common.controller.BaseController;
import com.jhgsys.internal.common.entity.FebsConstant;
import com.jhgsys.internal.common.entity.FebsResponse;
import com.jhgsys.internal.common.entity.QueryRequest;
import com.jhgsys.internal.common.exception.FebsException;
import com.jhgsys.internal.common.utils.BeanHelper;
import com.jhgsys.internal.common.utils.FebsUtil;
import com.jhgsys.internal.hazard.dto.HazardExamineDto;
import com.jhgsys.internal.hazard.dto.HazardExamineObjectDto;
import com.jhgsys.internal.hazard.dto.HazardExamineTeamDto;
import com.jhgsys.internal.hazard.entity.HazardExamine;
import com.jhgsys.internal.hazard.entity.HazardExamineObject;
import com.jhgsys.internal.hazard.entity.HazardExamineTeamUser;
import com.jhgsys.internal.hazard.service.IHazardExamineObjectService;
import com.jhgsys.internal.hazard.service.IHazardExamineService;
import com.jhgsys.internal.system.entity.Dept;
import com.jhgsys.internal.system.service.IDeptService;
import com.wuwenze.poi.ExcelKit;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 *  Controller
 *
 * @author admin
 * @date 2024-08-19 14:13:44
 */
@Slf4j
@Validated
@Controller
public class HazardExamineController extends BaseController {

    @Autowired
    private IHazardExamineService hazardExamineService;

    @Autowired
    private IDeptService deptService;

    @Autowired
    private IBaseProjectService baseProjectService;

    @Autowired
    private IHazardExamineObjectService hazardExamineObjectService;

    @Autowired
    private IHazardExamineUserService hazardExamineUserService;

    @Autowired
    private IBaseCautionaryLessonService baseCautionaryLessonService;

    @GetMapping(FebsConstant.VIEW_PREFIX + "hazardExamine")
    @RequiresPermissions("hazardExamine:view")
    public String hazardExamineIndex(Model model){
        setModelAttribute(model);
        return FebsUtil.view("hazard/hazardExamine/hazardExamineList");
    }

    @GetMapping(FebsConstant.VIEW_PREFIX + "hazardExamine/add")
    @RequiresPermissions("hazardExamine:add")
    public String hazardExamineAdd(Model model){
        model.addAttribute("hazardExamine",new HazardExamine());
        setModelAttribute(model);
        return FebsUtil.view("hazard/hazardExamine/hazardExamineEdit");
    }

    @GetMapping(FebsConstant.VIEW_PREFIX + "hazardExamine/update/{id}")
    @RequiresPermissions("hazardExamine:edit")
    public String hazardExamineUpdate(Model model, @PathVariable("id") String id) throws JsonProcessingException {
        setModelAttribute(model);
        HazardExamineDto hazardExamineDto = this.hazardExamineService.findHazardExamineById(id);
        model.addAttribute("hazardExamine", JSON.parse(new ObjectMapper().writeValueAsString(hazardExamineDto)));
        return FebsUtil.view("hazard/hazardExamine/hazardExamineEdit");
    }

    @GetMapping(FebsConstant.VIEW_PREFIX + "hazardExamine/detail/{id}")
    @RequiresPermissions("hazardExamine:view")
    public String hazardExamineDetail(Model model, @PathVariable("id") String id) throws JsonProcessingException {
        setModelAttribute(model);
        HazardExamineDto hazardExamineDto = this.hazardExamineService.findHazardExamineById(id);
        model.addAttribute("hazardExamine", JSON.parse(new ObjectMapper().writeValueAsString(hazardExamineDto)));
        return FebsUtil.view("hazard/hazardExamine/hazardExamineBaseInfoDetail");
    }

    @GetMapping(FebsConstant.VIEW_PREFIX + "hazardExamine/detailForLesson/{id}/{lessonId}")
    @RequiresPermissions("hazardExamine:view")
    public String hazardExamineDetailForLesson(Model model, @PathVariable("id") String id, @PathVariable("lessonId") String lessonId) throws JsonProcessingException {
        setModelAttribute(model);
        HazardExamineDto hazardExamineDto = this.hazardExamineService.findHazardExamineById(id);
        model.addAttribute("hazardExamine", JSON.parse(new ObjectMapper().writeValueAsString(hazardExamineDto)));
        model.addAttribute("baseCautionaryLesson", baseCautionaryLessonService.findBaseCautionaryLessonById(lessonId));
        return FebsUtil.view("base/baseCautionaryLesson/hazardExamineBaseInfoDetailForLesson");
    }

    /**
     * 查询（所有）
     * @author admin
     * @date 2024-08-19 14:13:44
     */
    @GetMapping("hazardExamine")
    @ResponseBody
    @RequiresPermissions("hazardExamine:view")
    public FebsResponse getAllHazardExamines(HazardExamine hazardExamine) {
        return new FebsResponse().success().data(hazardExamineService.findHazardExamineList(hazardExamine));
    }

    /**
     * 查询（分页）
     * @author admin
     * @date 2024-08-19 14:13:44
     */
    @GetMapping("hazardExamine/list")
    @ResponseBody
    @RequiresPermissions("hazardExamine:view")
    public FebsResponse hazardExamineList(QueryRequest request, HazardExamineDto hazardExamineDto) {
        if(null == hazardExamineDto.getTenantId()){
            hazardExamineDto.setTenantId(getCurrentTenantId());
        }
        hazardExamineDto.setUserId(getCurrentUser().getUserId());
        Map<String, Object> dataTable = getDataTable(this.hazardExamineService.findHazardExaminePage(request, hazardExamineDto));
        return new FebsResponse().success().data(dataTable);
    }

    /**
     * 查询（分页）包含安全记录录入信息
     * @author admin
     * @date 2024-08-19 14:13:44
     */
    @GetMapping("hazardExamine/listWithHazardExamineRecords")
    @ResponseBody
    @RequiresPermissions("hazardExamine:view")
    public FebsResponse listWithHazardExamineRecords(QueryRequest request, HazardExamineDto hazardExamineDto) {
        hazardExamineDto.setUserId(getCurrentUser().getUserId());
        Map<String, Object> dataTable = getDataTable(this.hazardExamineService.findHazardExaminePageWithRecords(request, hazardExamineDto));
        return new FebsResponse().success().data(dataTable);
    }

    /**
     * 新增 HazardExamine
     * @author admin
     * @date 2024-08-19 14:13:44
     */
    @Log("新增HazardExamine")
    @PostMapping("hazardExamine")
    @ResponseBody
    @RequiresPermissions("hazardExamine:add")
    public FebsResponse addHazardExamine(@RequestBody HazardExamineDto hazardExamineDto) throws FebsException {
        try {
            checkNecessaryColumns(hazardExamineDto,false);
            HazardExamine hazardExamine = BeanHelper.copyProperties(hazardExamineDto, HazardExamine.class);
            hazardExamine.setCreatedBy(getCurrentUser().getUserName());
            hazardExamine.setExamineNo(hazardExamineService.createExamineNo(hazardExamineDto.getTenantId()));
            this.hazardExamineService.createHazardExamine(hazardExamine);
            //保存检查项 hazard_examine_object
            if(CollectionUtils.isNotEmpty(hazardExamineDto.getObjectList())){
                hazardExamineDto.setExamineId(hazardExamine.getExamineId());
                saveHazardExamineObject(hazardExamineDto);
            }
            return new FebsResponse().success();
        } catch (Exception e) {
            String message = "新增HazardExamine失败";
            log.error(message, e);
            return failure(e,message);
        }
    }

    /**
     * 保存检查项
     * @author admin
     * @date 2024-09-04 14:13:44
     */
    private void saveHazardExamineObject(HazardExamineDto hazardExamineDto){
        //先删除hazard_examine_object
        hazardExamineObjectService.deleteByExamineIds(hazardExamineDto.getExamineId());
        List<HazardExamineObjectDto> objectList = hazardExamineDto.getObjectList();
        //先删除hazard_examine_user
        hazardExamineUserService.deleteByHazardExamineIds(hazardExamineDto.getExamineId());
        for (HazardExamineObjectDto d : objectList) {
            HazardExamineObject hazardExamineObject = BeanHelper.copyProperties(d, HazardExamineObject.class);
            hazardExamineObject.setExamineId(hazardExamineDto.getExamineId());
            hazardExamineObject.setCreatedTime(new Date());
            hazardExamineObject.setCreatedBy(getCurrentUserId());
            hazardExamineObjectService.save(hazardExamineObject);
            //保存安全检查成员 hazard_examine_user
            if (CollectionUtils.isNotEmpty(d.getTeamList())) {
                List<HazardExamineTeamDto> teamList = d.getTeamList();
                teamList.forEach(t ->{
                    List<HazardExamineTeamUser> teamUserList = t.getTeamUserList();
                    List<HazardExamineUser> hazardExamineUserList = teamUserList.stream().map(p -> {
                        HazardExamineUser hazardExamineUser = BeanHelper.copyProperties(p, HazardExamineUser.class);
                        hazardExamineUser.setExamineObjectId(hazardExamineObject.getExamineObjectId());
                        hazardExamineUser.setExamineId(hazardExamineDto.getExamineId());
                        hazardExamineUser.setCreatedTime(new Date());
                        hazardExamineUser.setCreatedBy(getCurrentUserId());
                        hazardExamineUser.setDeptId(p.getUserDeptId());
                        hazardExamineUser.setDeptName(p.getUserDeptName());
                        hazardExamineUser.setGroupName(t.getTeamName());
                        return hazardExamineUser;
                    }).collect(Collectors.toList());
                    hazardExamineUserService.saveBatch(hazardExamineUserList);
                });
            }
        }
    }

    /**
     * 逻辑删除 HazardExamine
     * @author admin
     * @date 2024-08-19 14:13:44
     */
    @Log("逻辑删除HazardExamine")
    @GetMapping("hazardExamine/delete/{id}")
    @ResponseBody
    @RequiresPermissions("hazardExamine:delete")
    public FebsResponse deleteHazardExamine(@PathVariable("id") String hazardExamineIds) throws FebsException {
        try {
            HazardExamine hazardExamine = new HazardExamine();
            hazardExamine.setDeletedBy(getCurrentUser().getUserName());
            hazardExamine.setDeletedTime(new Date());
            hazardExamine.setDeletedFlg(FebsConstant.INVALID);
            this.hazardExamineService.deleteHazardExamine(hazardExamine,hazardExamineIds);
            return new FebsResponse().success();
        } catch (Exception e) {
            String message = "删除HazardExamine失败";
            log.error(message, e);
            return failure(e,message);
        }
    }

    /**
    * 物理删除 HazardExamine
    * @author admin
    * @date 2024-08-19 14:13:44
    */
    @Log("物理删除HazardExamine")
    @GetMapping("hazardExamine/physicallyDelete/{id}")
    @ResponseBody
    @RequiresPermissions("hazardExamine:delete")
    public FebsResponse physicallyDeleteHazardExamine(@PathVariable("id") String hazardExamineIds) throws FebsException {
        try {
            this.hazardExamineService.physicallyDeleteHazardExamine(hazardExamineIds);
            return new FebsResponse().success();
        } catch (Exception e) {
            String message = "删除HazardExamine失败";
            log.error(message, e);
            return failure(e,message);
        }
    }

    /**
     * 修改 HazardExamine
     * @author admin
     * @date 2024-08-19 14:13:44
     */
    @Log("修改HazardExamine")
    @PostMapping("hazardExamine/update")
    @ResponseBody
    @RequiresPermissions("hazardExamine:edit")
    public FebsResponse updateHazardExamine(@RequestBody HazardExamineDto hazardExamineDto) throws FebsException {
        if(hazardExamineService.ifClosed(hazardExamineDto.getExamineId())){
            throw new FebsException("安全检查已结束！");
        }
        checkNecessaryColumns(hazardExamineDto,true);
        try {
            hazardExamineDto.setUpdatedBy(getCurrentUser().getUserName());
            this.hazardExamineService.updateHazardExamine(hazardExamineDto);
            //保存检查项 hazard_examine_object
            if(CollectionUtils.isNotEmpty(hazardExamineDto.getObjectList())){
                saveHazardExamineObject(hazardExamineDto);
            }
            return new FebsResponse().success();
        } catch (Exception e) {
            String message = "修改HazardExamine失败";
            log.error(message, e);
            return failure(e,message);
        }
    }

    /**
     * 导出 HazardExamine的excel
     * @author admin
     * @date 2024-08-19 14:13:44
     */
    @PostMapping("hazardExamine/excel")
    @ResponseBody
    @RequiresPermissions("hazardExamine:view")
    public void export(QueryRequest queryRequest, HazardExamineDto hazardExamine, HttpServletResponse response) throws FebsException {
        try {
            List<HazardExamineDto> hazardExamines = this.hazardExamineService.findHazardExaminePage(queryRequest, hazardExamine).getRecords();
            ExcelKit.$Export(HazardExamine.class, response).downXlsx(hazardExamines, false);
        } catch (Exception e) {
            String message = "导出Excel失败";
            log.error(message, e);
            throw new FebsException(message);
        }
    }

    private void setModelAttribute(Model model){
        model.addAttribute("currentUser",getCurrentUser());
        model.addAttribute("tenantList", getTenantList());
        model.addAttribute("tenantId", getCurrentTenantId());
        model.addAttribute("hasHeadCompanyRole", hasHeadCompanyRole());
        //部门
        List<Dept> deptList = deptService.list(new LambdaQueryWrapper<Dept>()
                .eq(Dept::getTenantId,getCurrentTenantId())
                .eq(Dept::getDeletedFlg,FebsConstant.VALID));
        model.addAttribute("deptList",deptList);
        //项目
        BaseProject baseProject = new BaseProject();
        baseProject.setTenantId(getCurrentTenantId());
        baseProject.setStatus("1");
        List<BaseProject> projectList = baseProjectService.findBaseProjects(baseProject);
        model.addAttribute("projectList",projectList);
    }

    /**
     * 新增/编辑保存时，字段必填项校验
     * @author dinghaitao
     * @date 2024-08-30 17:06:50
     */
    public void checkNecessaryColumns(HazardExamineDto hazardExamineDto,boolean editFlg) throws FebsException {
        if(editFlg && StringUtils.isEmpty(hazardExamineDto.getExamineId())){
            throw new FebsException("主键不能为空");
        } else if(StringUtils.isEmpty(hazardExamineDto.getExamineType())){
            throw new FebsException("检查类型不能为空");
        } else if(null==hazardExamineDto.getExamineCategory()){
            throw new FebsException("检查类别不能为空");
        } else if(StringUtils.isEmpty(hazardExamineDto.getExamineTitle())){
            throw new FebsException("检查标题不能为空");
        }
    }

}
